import { comboHolder, filterAuth } from '@/support/common';
import { PlusOutlined } from '@ant-design/icons';
import {
  Button,
  Card,
  Col,
  Divider,
  Drawer,
  Form,
  Input,
  message,
  Row,
  Space,
  Spin,
  Tag,
  Tree,
} from 'antd';
import { FormInstance } from 'antd/lib/form';
import { connect } from 'dva';
import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import PateoAuthButtons from '../../../components/common/PateoAuthButtons';
import PateoSearchForm from '../../../components/common/PateoSearchForm';
import PateoTable from '../../../components/common/PateoTable';
import styles from '../../../components/common/PateoTable/TableList.less';
import MaskText from '@/components/MaskText';

const itemTypes = {
  0: { value: '菜单', color: '#1890ff' },
  2: { value: '按钮', color: '#52c41a' },
  1: { value: '页面', color: '#f5222d' },
};
const { TreeNode } = Tree;
const FormItem = Form.Item;
const mapStateToProps = (state: any) => ({
  role: state.role,
  loading: state.loading.effects['role/postFetchPage'],
  saveLoading: state.loading.effects['role/postObj'],
  detailLoading: state.loading.effects['role/getData'],
});
class Role extends PureComponent<any, any> {
  formRef = React.createRef<FormInstance>();

  static contextTypes = {
    permissions: PropTypes.array,
  };

  constructor(props: any) {
    super(props);
    this.state = {
      formValues: {},
      visible: false,
      checkedKeys: {},
      expandedKeys: [],
      roleData: {},
      isView: false,
      isAdd: false,
    };
  }

  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'role/postFetchPage',
      payload: { url: '/role/page' },
    });
  }

  componentWillUnmount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'role/initData',
    });
  }

  handleFlushPage = () => {
    const { dispatch } = this.props;
    const { formValues } = this.state;
    dispatch({
      type: 'role/postFetchPage',
      payload: { url: '/role/page', ...formValues },
    });
  };

  close = () => {
    this.setState({
      visible: false,
      isView: false,
      isAdd: false,
      checkedKeys: {},
      expandedKeys: [],
      roleData: {},
    });
    this.formRef.current?.resetFields();
  };

  open = async (roleCode: any, isView: any) => {
    const { dispatch } = this.props;
    let param = {};
    let isAdd = true;
    if (roleCode) {
      isAdd = false;
      param = { roleCode: roleCode };
    }
    this.setState({ visible: true, isView: isView, isAdd: isAdd });
    const response = await dispatch({
      type: 'role/getData',
      payload: {
        url: '/role/detail',
        ...param,
      },
    });
    if (response.statusCode === '0') {
      let checked: any = [];
      let halfChecked: any = [];
      if (roleCode) {
        const fillFileds = [
          { name: 'roleName', value: response.data.roleName },
          { name: 'roleDesc', value: response.data.roleDesc },
        ];
        this.formRef.current?.setFields(fillFileds);
      }
      this.getCheckedKeys(response.data.resources, checked, halfChecked);
      this.setState({
        roleData: response.data,
        checkedKeys: { checked: checked, halfChecked: halfChecked },
      });
    }
  };

  renderTreeNodes = (data: any) => {
    return (
      data &&
      data.map((item: any) => {
        if (item.children && item.children.length > 0) {
          return (
            <TreeNode
              title={
                <span>
                  <Tag
                    style={{ marginRight: 0 }}
                    color={
                      typeof item.resourceType === 'number' && itemTypes[item.resourceType].color
                    }
                  >
                    {item.resourceName}
                  </Tag>
                </span>
              }
              key={item.resourceSid}
            >
              {this.renderTreeNodes(item.children)}
            </TreeNode>
          );
        } else {
          delete item.children;
        }
        return (
          <TreeNode
            key={item.resourceSid}
            title={
              item.resourceType !== 0 ? (
                <Tag
                  style={{ marginRight: 0 }}
                  color={
                    typeof item.resourceType === 'number' && itemTypes[item.resourceType].color
                  }
                >
                  {item.resourceName}
                </Tag>
              ) : (
                <span>
                  <Tag
                    style={{ marginRight: 0 }}
                    color={
                      typeof item.resourceType == 'number' && itemTypes[item.resourceType].color
                    }
                  >
                    {item.resourceName}
                  </Tag>
                </span>
              )
            }
          />
        );
      })
    );
  };

  getCheckedKeys = (data: any, checked: any, halfChecked: any) => {
    data.map((item: any) => {
      if (item.checked == 1) {
        checked.push(item.resourceSid);
      }
      if (item.checked == 2) {
        halfChecked.push(item.resourceSid);
      }
      if (item.children && item.children.length > 0) {
        this.getCheckedKeys(item.children, checked, halfChecked);
      }
    });
  };

  onCheck = (checkedKeys: any, e: any) => {
    const checkedObj = { checked: checkedKeys, halfChecked: e.halfCheckedKeys };
    this.setState({ checkedKeys: { ...checkedObj } });
  };

  handleSubmit = () => {
    this.formRef.current?.submit();
  };

  onFinish = (values: any) => {
    const { dispatch } = this.props;
    const { checkedKeys, roleData } = this.state;
    const checkedArr = checkedKeys.checked || [];
    const halfCheckedArr = checkedKeys.halfChecked || [];
    const resourceSids = [...checkedArr, ...halfCheckedArr];
    if (roleData && roleData.roleCode) {
      dispatch({
        type: 'role/postObj',
        payload: {
          url: '/role/edit',
          ...values,
          roleCode: roleData.roleCode,
          resourceList: resourceSids,
        },
        callback: (res: any) => {
          message.success('保存成功');
          this.close();
          this.handleFlushPage();
        },
      });
    } else {
      dispatch({
        type: 'role/postObj',
        payload: {
          url: '/role/add',
          ...values,
          resourceList: resourceSids,
        },
        callback: (res: any) => {
          message.success('保存成功');
          this.close();
          this.handleFlushPage();
        },
      });
    }
  };

  handleRemove = (roleCode: any) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'role/delData',
      payload: {
        url: '/role/del?roleCode=' + roleCode,
      },
      callback: (res: any) => {
        message.success('删除成功！');
        this.handleFlushPage();
      },
    });
  };

  render() {
    const {
      role: {
        pageData: { list, pagination },
      },
      loading,
      saveLoading,
      detailLoading,
      location: { pathname = '/' },
    } = this.props;
    const { formValues, visible, expandedKeys, checkedKeys, roleData, isView, isAdd } = this.state;
    const columns = [
      {
        title: '序号',
        dataIndex: 'index',
        width: 60,
        render: (text: any, record: any, index: any) => {
          return index + 1 + (pagination.current - 1) * pagination.pageSize;
        },
      },
      {
        title: '租户名称',
        dataIndex: 'tenantName',
      },
      {
        title: '角色名称',
        dataIndex: 'roleName',
      },
      {
        title: '角色描述',
        dataIndex: 'roleDesc',
      },
      {
        title: '已关联账号',
        dataIndex: 'accountCount',
      },
      {
        title: '已关联菜单',
        dataIndex: 'resourceCount',
      },
      {
        title: '创建人',
        dataIndex: 'createBy',
        render: (text: any) => {
          return <MaskText text={text} type="name" />;
        },
      },
      {
        title: '创建时间',
        dataIndex: 'createDate',
      },
      {
        title: '操作',
        dataIndex: '操作',
        fixed: 'right',
        width: 140,
        render: (text: any, record: any) => {
          const btns = [
            {
              title: '详情',
              key: 'detail',
              auth: 'role_doDetail',
              onConfirm: () => this.open(record.roleCode, true),
            },
            {
              title: '编辑',
              key: 'edit',
              auth: 'role_doEdit',
              onConfirm: () => this.open(record.roleCode, false),
            },
            {
              title: '删除',
              key: 'del',
              auth: 'role_doDel',
              Popconfirm: true,
              message: '是否确认删除？',
              onConfirm: () => this.handleRemove(record.roleCode),
            },
          ];
          return <PateoAuthButtons btns={btns} max={1} pathname={pathname} />;
        },
      },
    ];
    const paginationProps = {
      showSizeChanger: true,
      showQuickJumper: true,
      ...pagination,
      showTotal: () => (
        <span>共&nbsp;{pagination === undefined ? 0 : pagination.total}&nbsp;条</span>
      ),
    };
    const tableProps = {
      columns,
      dataSource: list,
      loading,
      rowKey: (record: any) => record.roleCode,
      pagination: paginationProps,
      scroll: { x: 'max-content' },
    };
    const searchItems = [
      {
        type: 'input',
        title: '角色名称',
        key: 'roleName',
      },
    ];
    return (
      <div>
        <Card bordered={false}>
          <PateoSearchForm
            searchItems={searchItems}
            fetchParams={{ type: 'role/postFetchPage', url: '/role/page' }}
            saveFormValues={(val: any) =>
              this.setState({ formValues: Object.assign(formValues, val) })
            }
            handleFormReset={() => this.setState({ formValues: {} })}
          />
        </Card>
        <Card className={styles.standardTable}>
          {filterAuth('role_doAdd', this.context.permissions, pathname) ? (
            <div className="my_newItem">
              <Button
                size="small"
                icon={<PlusOutlined />}
                type="primary"
                onClick={() => this.open(null, false)}
              >
                新增
              </Button>
            </div>
          ) : null}
          <PateoTable
            extraHandle={true}
            tableProps={tableProps}
            fetchParams={{ type: 'role/postFetchPage', url: '/role/page' }}
            formValues={formValues}
          />
        </Card>
        <Drawer
          title={isView ? '详情' : isAdd ? '新增角色' : '编辑角色'}
          onClose={this.close}
          visible={visible}
          closable={false}
          bodyStyle={{ padding: '12px 0px 12px 24px' }}
          width={600}
          extra={
            <Space>
              <Button size="small" onClick={this.close}>
                {isView ? '关闭' : '取消'}
              </Button>
              {isView ? null : (
                <Button
                  size="small"
                  loading={saveLoading || detailLoading}
                  onClick={this.handleSubmit}
                  type="primary"
                >
                  保存
                </Button>
              )}
            </Space>
          }
        >
          <Spin spinning={detailLoading}>
            <Row style={{ height: 'calc(100vh - 81px)' }}>
              <Col span={11}>
                <Form
                  ref={this.formRef}
                  layout="vertical"
                  hideRequiredMark
                  onFinish={this.onFinish}
                >
                  <FormItem
                    name="roleName"
                    label="角色名称"
                    rules={[{ required: true, message: comboHolder('角色名称') }]}
                  >
                    <Input placeholder={comboHolder('角色名称')} maxLength={30} disabled={isView} />
                  </FormItem>
                  <FormItem
                    name="roleDesc"
                    label="角色描述"
                    rules={[{ required: false, message: comboHolder('角色描述') }]}
                  >
                    <Input.TextArea
                      rows={4}
                      placeholder={comboHolder('角色描述')}
                      disabled={isView}
                    />
                  </FormItem>
                </Form>
              </Col>
              <Col span={2} style={{ textAlign: 'center' }}>
                <Divider type="vertical" style={{ height: '100%' }} />
              </Col>
              <Col span={11} style={{ height: '100%', overflowY: 'auto' }}>
                <Tree
                  checkable
                  disabled={isView}
                  onCheck={this.onCheck}
                  onExpand={(keys: any) => this.setState({ expandedKeys: keys })}
                  expandedKeys={expandedKeys}
                  checkedKeys={checkedKeys}
                >
                  {this.renderTreeNodes(roleData.resources)}
                </Tree>
              </Col>
            </Row>
          </Spin>
        </Drawer>
      </div>
    );
  }
}
export default connect(mapStateToProps)(Role);
